#pragma once

#include <iostream>
#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <string>
#include <sys/stat.h>
#include <cstdlib>
#include <cstring>
#include "log.hpp"

using namespace std;

const string pathname = "/home/wj"; // ftok函数的第一个参数
int proj_id = 'A';                  // ftok函数的第二个参数
log l;                              // 日志对象

key_t Getkey()
{
    key_t key = ftok(pathname.c_str(), proj_id);
    if (key == -1)
    {
        l.logmessage(Fatal, "ftok error: %s", strerror(errno));
        exit(1);
    }
    l.logmessage(Info, "ftok success, key is: 0x%x", key);
    return key;
}

int GetShareMem()
{
    key_t key = Getkey();
    int shmid = shmget(key, 4096, IPC_CREAT | IPC_EXCL | 0666);
    if (shmid == -1)
    {
        l.logmessage(Fatal, "create share memory error: %s", strerror(errno));
    }
    l.logmessage(Info, "create share memory success, shmid is %d", shmid);
    return shmid;
}

int GetShm()
{
    // 大小：获取一个已存在的共享内存段的标识符，这个参数可以设置为0来表示忽略
    // 第三个参数：获取已存在的共享内存时，可以设置为 0
    return shmget(Getkey(), 0, 0);
}

// ================== 命名管道 ==============================
enum
{
    // 规定错误码从1开始递增
    MKFIFO_FAIL = 1, // 创建匿名管道失败
    UNLINK_FAIL,     // 删除匿名管道失败
    OPEN_FAIL        // 打开文件失败
};

class Init
{
public:
    Init()
    {
        // 创建管道
        int n = mkfifo("./myfifo", 0664);
        if (n == -1)
        {
            perror("mkfifo");
            exit(MKFIFO_FAIL);
        }
    }
    ~Init()
    {
        int m = unlink("./myfifo");
        if (m == -1)
        {
            perror("unlink");
            exit(UNLINK_FAIL);
        }
    }
};

